/*------------------------------------------------------------*
*-------------------------------------------------------------*/

#include "nand_lut.h"
#include "nand_w25n.h"
#include "stdlib.h"
#include "string.h"
#include "mytype.h"

/*****************************************************************************
* @brief   INFO
*****************************************************************************/
extern nand_attriute nand_dev;

#define W25N_PAGE_MAIN_SIZE               2048
#define W25N_PAGE_SPARE_SIZE              64
#define W25N_PAGE_SIZE                    (W25N_PAGE_MAIN_SIZE + W25N_PAGE_SPARE_SIZE)
#define W25N_PAGE_PER_BLOCK               64            
#define W25N_BLOCK_TOTAL                  1024


/*****************************************************************************
* @brief   hal interface link
*****************************************************************************/
char nand_lut_dev_link(void)
{
	dword_tt id;
	char cnt;
	
	// spi nand hal link
	nand_dev.nand_opt.ecc_error_get = spi_nand_ecc_error_get;
	nand_dev.nand_opt.read_page = spi_nand_read_page;
	nand_dev.nand_opt.read_cache = spi_nand_q_read_cache;
	nand_dev.nand_opt.write_cache = spi_nand_q_write_cache;
	nand_dev.nand_opt.program_exe = spi_nand_program_exe;
	nand_dev.nand_opt.init = w25n_init;
	nand_dev.nand_opt.block_erase = spi_nand_block_erase;

	// chip infomation recognize
    for(cnt = 0; cnt < 5; cnt++)
    {
        // read ID
        id.uVal = 0;
		spi_nand_read_id(id.v);
		
        // gd5 1Gbits
        if (id.uVal == 0xD1C8)
        {
			spi_nand_info.block_total = W25N_BLOCK_TOTAL;
			spi_nand_info.page_main_size = W25N_PAGE_MAIN_SIZE;
			spi_nand_info.page_spare_size = W25N_PAGE_SPARE_SIZE;
			spi_nand_info.page_per_block = W25N_PAGE_PER_BLOCK;
			
            nand_dev.page_size = W25N_PAGE_SIZE;
            nand_dev.page_main_size = W25N_PAGE_MAIN_SIZE;
            nand_dev.page_spare_size = W25N_PAGE_SPARE_SIZE;
            nand_dev.page_per_block = W25N_PAGE_PER_BLOCK;
            nand_dev.block_per_plane = W25N_BLOCK_TOTAL;
            nand_dev.block_total = W25N_BLOCK_TOTAL;
            nand_dev.logic_block_amount = W25N_BLOCK_TOTAL*7/8;
			
			nand_dev.nand_opt.init = gd5_init;
			
			return 1;
        }
        
		// w25n 1Gbits
        if((id.uVal & 0xFFFFFF00) == 0x21AAEF00)
        {
			spi_nand_info.block_total = W25N_BLOCK_TOTAL;
			spi_nand_info.page_main_size = W25N_PAGE_MAIN_SIZE;
			spi_nand_info.page_spare_size = W25N_PAGE_SPARE_SIZE;
			spi_nand_info.page_per_block = W25N_PAGE_PER_BLOCK;
			
            nand_dev.page_size = W25N_PAGE_SIZE;
            nand_dev.page_main_size = W25N_PAGE_MAIN_SIZE;
            nand_dev.page_spare_size = W25N_PAGE_SPARE_SIZE;
            nand_dev.page_per_block = W25N_PAGE_PER_BLOCK;
            nand_dev.block_per_plane = W25N_BLOCK_TOTAL;
            nand_dev.block_total = W25N_BLOCK_TOTAL;
            nand_dev.logic_block_amount = W25N_BLOCK_TOTAL*7/8;
			
            return 1;
        }
    }
	
	return 0;
}

/*****************************************************************************
* @brief   返回1代表出错，中断操作
*****************************************************************************/
uint8_t nand_lut_write_dat_get(uint32_t addr_offset, uint8_t *pdat, uint16_t len)
{
    return 0;
}

/*****************************************************************************
* @brief   等待电源电压正常，此函数在页写入之前执行
*****************************************************************************/
char nand_power_wait(void)
{
    return 1;
}
